#include "Game.h"

IGame* createGame( HINSTANCE hInst, HWND hWnd )
{
	return new Game( hInst, hWnd );
}

Game::Game( HINSTANCE hInst, HWND hWnd ) :
	m_input( hInst, hWnd )
{
	// initialize camera
	m_camera.hand = Camera::RIGHTHANDED;

	m_camera.eye = float3( 0, 0, 20.f );
	m_camera.at  = float3( 0, 0, 0 );
	m_camera.up  = float3( 0, 1, 0 );

	m_camera.projectionType = Camera::PERSPECTIVE_FOV;
	m_camera.perspectiveFov.fovy = D3DXToRadian(45.f);
	m_camera.perspectiveFov.aspect = 1024.f/768.f;

	m_camera.zn = 1.0f;
	m_camera.zf = 100.0f;

	m_polygon_center = float3(0,0,0);
	m_polygon2_center = float3(1,-2,0);
	m_polygonMove_center = float3(-6,0,0);
	m_polygonMove_destination = float3(6,0,0);

	// initialize polygon
	m_polygon.push_back( float3( -0.5, -0.5, 0 ) );
	m_polygon.push_back( float3( 0.5, -0.5, 0 ) );
	m_polygon.push_back( float3( 0.5, 0.5, 0 ) );
	m_polygon.push_back( float3( -0.5, 0.5, 0 ) );

	m_polygonVector.push_back(m_polygon);

	
	m_polygon.clear();

	m_polygon.push_back( float3( -0.5, -0.5, 0 ) + m_polygon2_center);
	m_polygon.push_back( float3( 0.5, -0.5, 0 ) + m_polygon2_center );
	m_polygon.push_back( float3( 0.5, 0.5, 0 ) + m_polygon2_center  );
	m_polygon.push_back( float3( -0.5, 0.5, 0 ) + m_polygon2_center );

	m_polygonVector.push_back(m_polygon);

	m_polygon.clear();
	


	for( int i = 0; i < 10; i++ )
	{
		m_polygonMove.push_back( float3( cos(TWO_PI*i/10), sin(TWO_PI*i/10), 0 )/8.0f );
	}
	
	pathOn = true;
	moving = false;
	path.begin(m_polygonMove_center, m_polygonMove_destination, m_polygonVector);

}

Game::~Game()
{
	m_polygonView.destroy();
	m_d3dDevice = 0;
}

void Game::onCreateGraphics( D3DDevice device )
{
	m_d3dDevice = device;
	m_polygonMoveView.initialize( m_d3dDevice );

	m_polygonView.initialize(m_d3dDevice);
	m_polygonView.setup( m_polygonVector[0], float4( 1.0f, 1.0f, 1.0f, 1.0f ) );

	m_polygonMoveView.setup( m_polygonMove, float4( 0.0f, 0.0f, 1.0f, 1.0f ) );

	m_d3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	float44 world = identity44();
	float44 view = m_camera.view();
	float44 proj = m_camera.projection();

	m_d3dDevice->SetTransform( D3DTS_WORLD, &world );
	m_d3dDevice->SetTransform( D3DTS_VIEW, &view );
	m_d3dDevice->SetTransform( D3DTS_PROJECTION, &proj );
	
}

void Game::onResetGraphics( D3DDevice device )
{
	//TODO: Add code to handle lost device ( resizing issue )

	m_d3dDevice = device;

	
	m_polygonView.destroy();
	
	m_polygonMoveView.destroy();
	m_polygonMoveView.initialize( m_d3dDevice );
	
	
	m_polygonView.initialize(m_d3dDevice);
	m_polygonView.setup( m_polygonVector[0], float4( 1.0f, 1.0f, 1.0f, 1.0f ) );
	

	m_polygonMoveView.setup( m_polygonMove, float4( 0.0f, 0.0f, 1.0f, 1.0f ) );

	m_d3dDevice->SetRenderState( D3DRS_CULLMODE, D3DCULL_CW );

	float44 view = m_camera.view();
	float44 proj = m_camera.projection();

	m_d3dDevice->SetTransform( D3DTS_VIEW, &view );
	m_d3dDevice->SetTransform( D3DTS_PROJECTION, &proj );
}

void Game::onLostGraphics()
{
}

void Game::onFrameMove(float dt)
{	
	if(pathOn)
	{
		if(path.destinationVisible(m_polygonMove_center))
			nextPoint = path.next(m_polygonMove_center);
		//If character is not moving, grab the next point
		if(!moving)
		{
			nextPoint = path.next();
			moving = true;
		}

		//If character is within a specific distance of the next point, stop moving
		//(for higher FPS this value may go down - calculated by speed of the object*elapsed time)
		if(length(m_polygonMove_center - nextPoint) < 5*dt)
			moving = false;

		//Otherwise keep moving
		else
		{
			m_polygonMove_center += normalize(nextPoint-m_polygonMove_center)*5*dt;
		}

		//If the character has reached destination, turn off pathfinding
		if(length(m_polygonMove_center - m_polygonMove_destination) < 5*dt )
		{
			pathOn = false;
			path.end();
		}

	}
}

void Game::onFrameRender(float dt)
{
	m_polygonView.render( translation(m_polygon_center) );
	m_polygonView.render( translation(m_polygon2_center) );

	m_polygonMoveView.render( translation (m_polygonMove_center) );
}

void Game::onDestroyGraphics()
{
}
